home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 Extra Demos / User Contributions / ButtonBreakOut ƒ / ButtonBreakOut / ButtonBreakOut.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-11  |  34.9 KB  |  1,155 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // ButtonBreakOut.c
  3. // a revised version of SimpleBreakOut.c
  4. //
  5. // Portions are Copyright © 1993 Tony Myles, All rights reserved worldwide.
  6. //
  7. // Description: This is a very basic breakout type game that demonstrates
  8. // SpriteWorld's efficient handling of inactive sprites. 
  9. // It also shows how you can use ButtonSprites within your animation.
  10. ///--------------------------------------------------------------------------------------
  11. //    Search for:
  12. //
  13. //         button-related routines
  14. //
  15. //    to see the complete demo interface to buttons.
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19.  
  20. #include "SWIncludes.h"            // Automatically include all SpriteWorld.h files
  21. #include "SWGameUtils.h"
  22.  
  23. #include "SWApplication.h"
  24. #include "ButtonSprite.h"
  25. #include "ButtonBreakOut.h"
  26. #include "SpritePersistence.h"
  27. #include "DataPersistence.h"
  28.  
  29. #define kMaxFPS                    60                // Set to 0 for maximum speed
  30. #define kSyncToVBL                true            // Sync animation to VBL?
  31.  
  32. #define kPlayPictID                1000
  33. #define kPlayWidth                85
  34. #define kQuitPictID                1001
  35. #define kQuitWidth                85
  36. #define kDisabledPictID            1002
  37. #define kDisabledWidth            160
  38. #define kPausePictID            1003            // [DB]
  39. #define kPauseWidth                72                // [DB]
  40. #define kGiveUpPictID            1004            // [DB]
  41. #define kGiveUpWidth            94                // [DB]
  42.  
  43. enum
  44. {
  45.     kBallHorizDelta = 5,
  46.     kBallVertDelta = 5,
  47.     kNumberOfBrickColumns = 10,
  48.     kNumberOfBrickRows = 5,
  49.     kTotalNumberOfBricks = (kNumberOfBrickColumns * kNumberOfBrickRows),
  50.     kBrickCIconID = 129,
  51.     kBreakBallCIconID = 130,
  52.     kPaddleCIconID = 131,
  53.     kEraseWritingTimer = 60,
  54.     kEraseReadingTimer = 90
  55. };
  56.  
  57. Point                oldPoint, newPoint;            // Mouse variables used for moving paddle
  58. OSErr                err;
  59. PixPatHandle        pixPatH;
  60.  
  61. SpriteWorldPtr        spriteWorldP;
  62. SpriteLayerPtr        brickLayerP;
  63. SpriteLayerPtr        ballLayerP;
  64. SpriteLayerPtr        paddleLayerP;
  65. SpriteLayerPtr        buttonsLayerP;
  66. SpritePtr            brickSpriteArray[kTotalNumberOfBricks];
  67. SpritePtr            ballSpriteP;
  68. SpritePtr            paddleSpriteP;
  69. ButtonSpritePtr        playButtonSpritePtr;
  70. ButtonSpritePtr        quitButtonSpritePtr;
  71. ButtonSpritePtr        disabledButtonSpritePtr;
  72. ButtonSpriteRec        playButtonSpriteRec;
  73. ButtonSpriteRec        quitButtonSpriteRec;
  74. ButtonSpriteRec        disabledButtonSpriteRec;
  75.  
  76. ButtonSpritePtr        pauseButtonSpritePtr;                // [DB]
  77. ButtonSpritePtr        giveUpButtonSpritePtr;                // [DB]
  78. ButtonSpriteRec        pauseButtonSpriteRec;                // [DB]
  79. ButtonSpriteRec        giveUpButtonSpriteRec;                // [DB]
  80.  
  81. SInt16                horizOffset, vertOffset, brickHoriz, brickVert, col, row, n, QuitBreakOut, BrickNum;
  82. Boolean                PauseBreakOut             = false;    // [DB]
  83. Boolean                GiveUpBreakOut             = false;    // [DB]
  84. Rect                moveBoundsRect;
  85. long                PaddleWiggle;                          // during the demo this makes the paddle wiggle back and forth
  86.  
  87. CursHandle            FingerCursorHandle;
  88. CWindowPtr            srcWindowP;
  89.  
  90. Boolean                cursorVisible;                        // [DB]
  91.  
  92. UInt32                eraseTime                 = 0L;        // [DB]
  93. UInt32                countSaves                 = 0L;        // [DB]
  94. char                demoStr [256]             = {"<empty>"};        // [DB]
  95. SInt16                demoRez                 = 6666;        // [DB]
  96. SInt16                colorRez                = 1000;
  97.  
  98.  
  99. RGBColor            infoTextColor;                        // [DB]
  100.  
  101.  
  102. ///--------------------------------------------------------------------------------------
  103. // main
  104. ///--------------------------------------------------------------------------------------
  105.  
  106. void main(void)
  107. {
  108.     Rect        windRect;
  109.     
  110.     
  111.     Initialize(kNumberOfMoreMastersCalls);
  112.     
  113.     if (!SWHasSystem7())
  114.         CantRunOnThisMachine();
  115.         
  116.     SetCursor(*GetCursor(watchCursor));
  117.  
  118.         // Create and set up the window
  119.     srcWindowP = (CWindowPtr) GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
  120.  
  121.     if (srcWindowP != NULL)
  122.     {
  123.             // Center window in screen
  124.         windRect = srcWindowP->portRect;
  125.         CenterRect(&windRect, &qd.screenBits.bounds);
  126.         MoveWindow((WindowPtr) srcWindowP, windRect.left, windRect.top, false);
  127.         
  128.         ShowWindow((WindowPtr) srcWindowP);
  129.         SetPort((WindowPtr) srcWindowP);
  130.     }
  131.     else
  132.         CantFindResource();
  133.     
  134.  
  135.     PerformSimpleAnimation();
  136. }
  137.  
  138.  
  139. ///--------------------------------------------------------------------------------------
  140. // PerformSimpleAnimation
  141. ///--------------------------------------------------------------------------------------
  142.  
  143. void PerformSimpleAnimation(void)
  144. {
  145.     EventRecord        event;
  146.  
  147.     SetPort((GrafPtr)srcWindowP);
  148.  
  149.     //
  150.     // STEP #1: initialize the sprite world package
  151.     //
  152.  
  153.     err = SWEnterSpriteWorld();
  154.     FatalError(err);
  155.  
  156.  
  157.     //
  158.     // STEP #2: create the various pieces that we need
  159.     //
  160.  
  161.         // create the sprite world
  162.     err = SWCreateSpriteWorldFromWindow(&spriteWorldP, srcWindowP, NULL, NULL, 0);
  163.     FatalError(err);
  164.  
  165.         // create the brick layer
  166.     err = SWCreateSpriteLayer(&brickLayerP);
  167.     FatalError(err);
  168.  
  169.         // create the ball layer
  170.     err = SWCreateSpriteLayer(&ballLayerP);
  171.     FatalError(err);
  172.  
  173.         // create the paddle layer
  174.     err = SWCreateSpriteLayer(&paddleLayerP);
  175.     FatalError(err);
  176.  
  177.         // create the buttons layer
  178.     err = SWCreateSpriteLayer(&buttonsLayerP);
  179.     FatalError(err);
  180.  
  181.         // Create the first brick sprite
  182.     err = SWCreateSpriteFromCicnResource(spriteWorldP, &(brickSpriteArray[0]), NULL, 
  183.                 kBrickCIconID, 1, kNoMask);
  184.  
  185.         // Clone the other brick sprites off the first one
  186.     for (BrickNum = 1; BrickNum < kTotalNumberOfBricks; BrickNum++)
  187.     {
  188.         err = SWCloneSprite(brickSpriteArray[0], &brickSpriteArray[BrickNum], NULL);
  189.         FatalError(err);
  190.     }
  191.  
  192.         // create ball sprite
  193.     err = SWCreateSpriteFromCicnResource(spriteWorldP, &ballSpriteP, NULL, 
  194.                 kBreakBallCIconID, 1, kFatMask);
  195.     FatalError(err);
  196.  
  197.         // create paddle sprite
  198.     err = SWCreateSpriteFromCicnResource(spriteWorldP, &paddleSpriteP, NULL, 
  199.                 kPaddleCIconID, 1, kFatMask);
  200.     FatalError(err);
  201.  
  202.         // create play button sprite
  203.     err = SWCreateSpriteFromSinglePict(spriteWorldP, &(SpritePtr)playButtonSpritePtr, (SpritePtr)&playButtonSpriteRec,
  204.                 kPlayPictID, kPlayPictID, kPlayWidth,1, kFatMask);
  205.     FatalError(err);
  206.  
  207.     err = SWCreateSpriteFromSinglePict(spriteWorldP, &(SpritePtr)quitButtonSpritePtr, (SpritePtr)&quitButtonSpriteRec,
  208.                 kQuitPictID, kQuitPictID, kQuitWidth,1, kFatMask);
  209.     FatalError(err);
  210.  
  211.     err = SWCreateSpriteFromSinglePict(spriteWorldP, &(SpritePtr)disabledButtonSpritePtr, (SpritePtr)&disabledButtonSpriteRec,
  212.                 kDisabledPictID, kDisabledPictID, kDisabledWidth,1, kFatMask);
  213.     FatalError(err);
  214.  
  215.     err = SWCreateSpriteFromSinglePict(spriteWorldP, &(SpritePtr)pauseButtonSpritePtr, (SpritePtr)&pauseButtonSpriteRec,
  216.                 kPausePictID, kPausePictID, kPauseWidth,1, kFatMask);                        // [DB]
  217.     FatalError(err);
  218.  
  219.     err = SWCreateSpriteFromSinglePict(spriteWorldP, &(SpritePtr)giveUpButtonSpritePtr, (SpritePtr)&giveUpButtonSpriteRec,
  220.                 kGiveUpPictID, kGiveUpPictID, kGiveUpWidth,1, kFatMask);                    // [DB]
  221.     FatalError(err);
  222.  
  223.  
  224.  
  225.     //
  226.     // STEP #3: put the pieces together (must be done BEFORE the sprite world is locked!)
  227.     //
  228.  
  229.     for (BrickNum = 0; BrickNum < kTotalNumberOfBricks; BrickNum++)
  230.     {
  231.             // add the brick sprite to the brick layer
  232.         SWAddSprite(brickLayerP, brickSpriteArray[BrickNum]);
  233.     }
  234.  
  235.         // add the ball sprite to the ball layer
  236.     SWAddSprite(ballLayerP, ballSpriteP);
  237.  
  238.         // add the paddle sprite to the paddle layer
  239.     SWAddSprite(paddleLayerP, paddleSpriteP);
  240.  
  241.         // add the button sprites to the button layer
  242.     SWAddSprite(buttonsLayerP, (SpritePtr) playButtonSpritePtr);
  243.     SWAddSprite(buttonsLayerP, (SpritePtr) quitButtonSpritePtr);
  244.     SWAddSprite(buttonsLayerP, (SpritePtr) disabledButtonSpritePtr);
  245.     SWAddSprite(buttonsLayerP, (SpritePtr) pauseButtonSpritePtr);                    // [DB]
  246.     SWAddSprite(buttonsLayerP, (SpritePtr) giveUpButtonSpritePtr);                    // [DB]
  247.  
  248.     //
  249.     // STEP #4: set things up for the animation
  250.     // (can be done before or after locking the SpriteWorld)
  251.     //
  252.  
  253.         // calculate the movement boundary rectangle
  254.     moveBoundsRect = srcWindowP->portRect;
  255.  
  256.     horizOffset = (brickSpriteArray[0]->curFrameP->frameRect.right - brickSpriteArray[0]->curFrameP->frameRect.left) + 2;
  257.     vertOffset = (brickSpriteArray[0]->curFrameP->frameRect.bottom - brickSpriteArray[0]->curFrameP->frameRect.top) + 2;
  258.     brickHoriz = 2;
  259.     brickVert = (vertOffset * 2);
  260.     BrickNum = 0;
  261.  
  262.         // set up the bricks
  263.     for (col = 0; col < kNumberOfBrickColumns; col++)
  264.     {
  265.         brickVert = (vertOffset * 2);
  266.  
  267.         for (row = 0; row < kNumberOfBrickRows; row++)
  268.         {
  269.                 // set the sprite’s initial location
  270.             SWSetSpriteLocation(brickSpriteArray[BrickNum], brickHoriz, brickVert);
  271.             SWSetSpriteMoveTime(brickSpriteArray[BrickNum], -1);
  272.  
  273.             BrickNum++;
  274.             brickVert += vertOffset;
  275.         }
  276.     
  277.         brickHoriz += horizOffset;
  278.     }
  279.  
  280.         // set the buttons location
  281.     SWSetSpriteLocation((SpritePtr) playButtonSpritePtr, 100, 175);
  282.     SWSetSpriteLocation((SpritePtr) quitButtonSpritePtr, 100, 225);
  283.     SWSetSpriteLocation((SpritePtr) disabledButtonSpritePtr, 100, 275);
  284.     SWSetSpriteLocation((SpritePtr) pauseButtonSpritePtr, 30, 350);                    // [DB]
  285.     SWSetSpriteLocation((SpritePtr) giveUpButtonSpritePtr, 220, 350);                // [DB]
  286.     
  287.         // set the buttons callbacks
  288.     SWGSetUpButtonCallbacks    (playButtonSpritePtr, GenericDrawButtonUpProc, GenericDrawButtonMouseOverProc,
  289.                                     GenericDrawButtonDownProc, GenericDrawButtonDisabledProc, PlayProc);
  290.  
  291.     SWGSetUpButtonCallbacks    (quitButtonSpritePtr, GenericDrawButtonUpProc, GenericDrawButtonMouseOverProc,
  292.                                     GenericDrawButtonDownProc, GenericDrawButtonDisabledProc, QuitProc);
  293.  
  294.     SWGSetUpButtonCallbacks    (disabledButtonSpritePtr, GenericDrawButtonUpProc, GenericDrawButtonMouseOverProc,
  295.                                     GenericDrawButtonDownProc, GenericDrawButtonDisabledProc, nil);
  296.  
  297.     SWGSetUpButtonCallbacks    (pauseButtonSpritePtr, GenericDrawButtonUpProc, GenericDrawButtonMouseOverProc,
  298.                                     GenericDrawButtonDownProc, GenericDrawButtonDisabledProc, PauseProc);        // [DB]
  299.  
  300.     SWGSetUpButtonCallbacks    (giveUpButtonSpritePtr, GenericDrawButtonUpProc, GenericDrawButtonMouseOverProc,
  301.                                     GenericDrawButtonDownProc, GenericDrawButtonDisabledProc, GiveUpProc);        // [DB]
  302.  
  303.  
  304.         // set the ball’s movement characteristics
  305.     SWSetSpriteLocation(ballSpriteP, - 100, 50);
  306.     SWSetSpriteMoveBounds(ballSpriteP, &moveBoundsRect);
  307.     SWSetSpriteMoveDelta(ballSpriteP, kBallHorizDelta, kBallVertDelta);
  308.     SWSetSpriteMoveProc(ballSpriteP, BallMoveProc);
  309.     SWSetSpriteCollideProc(ballSpriteP, BallCollideProc);
  310.  
  311.         // set the paddle’s movement characteristics
  312.     SWSetSpriteMoveBounds(paddleSpriteP, &moveBoundsRect);
  313.     SetUpPaddle(paddleSpriteP);
  314.     SWSetSpriteMoveProc(paddleSpriteP, PaddleMoveProc);
  315.     SWSetSpriteCollideProc(paddleSpriteP, PaddleCollideProc);
  316.     
  317.     
  318.     //
  319.     // Set the DrawProcs to BlitPixie
  320.     //
  321.  
  322.         // Set the screen drawProcs
  323.     if (spriteWorldP->pixelDepth == 8)                        // 256 colors
  324.     {
  325.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
  326.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
  327.     }
  328.     else if ( !(SW_PPC && spriteWorldP->pixelDepth < 8) )    // Not 256 colors
  329.     {
  330.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
  331.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
  332.     }
  333.  
  334.         // add the layers to the world
  335.     SWAddSpriteLayer(spriteWorldP, brickLayerP);
  336.     SWAddSpriteLayer(spriteWorldP, ballLayerP);
  337.     SWAddSpriteLayer(spriteWorldP, paddleLayerP);
  338.     SWAddSpriteLayer(spriteWorldP, buttonsLayerP);    
  339.  
  340.         // Set the sprite drawProcs
  341.     if (spriteWorldP->pixelDepth == 8)                        // 256 colors
  342.     {
  343.         SWSetSpriteDrawProc(ballSpriteP, BlitPixie8BitMaskDrawProc);
  344.         SWSetSpriteDrawProc(paddleSpriteP, BlitPixie8BitRectDrawProc);
  345.     }
  346.     else if ( !(SW_PPC && spriteWorldP->pixelDepth < 8) )    // Not 256 colors
  347.     {
  348.         SWSetSpriteDrawProc(ballSpriteP, BlitPixieAllBitMaskDrawProc);
  349.         SWSetSpriteDrawProc(paddleSpriteP, BlitPixieAllBitRectDrawProc);
  350.     }
  351.     SWSetSpriteDrawProc((SpritePtr) playButtonSpritePtr, BlitPixie8BitMaskDrawProc);
  352.     SWSetSpriteDrawProc((SpritePtr) quitButtonSpritePtr, BlitPixie8BitMaskDrawProc);
  353.     SWSetSpriteDrawProc((SpritePtr) disabledButtonSpritePtr, BlitPixie8BitMaskDrawProc);
  354.     SWSetSpriteDrawProc((SpritePtr) pauseButtonSpritePtr, BlitPixie8BitMaskDrawProc);            // [DB]
  355.     SWSetSpriteDrawProc((SpritePtr) giveUpButtonSpritePtr, BlitPixie8BitMaskDrawProc);            // [DB]
  356.  
  357.     //
  358.     // Set the DrawProcs to BlitPixie
  359.     //
  360.  
  361.         // Set the screen drawProcs
  362.     if (spriteWorldP->pixelDepth == 8)                        // 256 colors
  363.     {
  364.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
  365.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
  366.     }
  367.     else if ( !(SW_PPC && spriteWorldP->pixelDepth < 8) )    // Not 256 colors
  368.     {
  369.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
  370.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
  371.     }
  372.     
  373.  
  374.     //
  375.     // STEP #5: lock the sprite world        !!! VERY IMPORTANT !!!
  376.     //
  377.  
  378.     SWLockSpriteWorld(spriteWorldP);
  379.     
  380.  
  381.     HideCursor();
  382.     cursorVisible = false;
  383.     
  384.     //
  385.     // SETP #6: Draw a nice background. Must be done *after* locking the SpriteWorld!
  386.     //
  387.  
  388.     SWSetPortToBackground(spriteWorldP);
  389.     
  390.     if (spriteWorldP->pixelDepth == 1)
  391.         pixPatH = GetPixPat(129);        // B&W dithered background
  392.     else
  393.         pixPatH = GetPixPat(128);        // Color
  394.     
  395.     if (pixPatH != NULL)
  396.     {
  397.         FillCRect(&moveBoundsRect, pixPatH);
  398.         DisposePixPat(pixPatH);
  399.     }
  400.  
  401.  
  402.     // [DB] add help info to background
  403.     {    
  404.         SInt16        x, y;
  405.         OSErr        err;
  406.         RGBColor    fore, back;
  407.         Rect        r;
  408.  
  409.         // read parms from file
  410.         err = SWGOpenPersistenceFile ();
  411.         SWGErrorReportingStub (err);                                            // beep only if err
  412.         err = SWGLoadRecord ((Ptr)&fore, sizeof (RGBColor), colorRez);
  413.         SWGErrorReportingStub (err);
  414.         err = SWGLoadRecord ((Ptr)&back, sizeof (RGBColor), colorRez + 1);
  415.         SWGErrorReportingStub (err);
  416.         err = SWGLoadRecord ((Ptr)&infoTextColor, sizeof (RGBColor), colorRez + 2);
  417.         SWGErrorReportingStub (err);
  418.         SWGClosePersistenceFile ();
  419.  
  420.         // writing pane    
  421.         r = qd.thePort->portRect;
  422.         r.top = moveBoundsRect.bottom - 220;
  423.         r.bottom = r.top + 170;
  424.         RGBBackColor (&back);
  425.         EraseRect (&r);
  426.  
  427.         // help text
  428.         TextFont (kFontIDNewYork);
  429.         TextSize (12);
  430.         TextMode (srcOr);
  431.         TextFace (bold);
  432.         RGBForeColor (&fore);
  433.  
  434.         x = moveBoundsRect.left + 20;
  435.         y = moveBoundsRect.bottom - 200;
  436.         MoveTo (x, y);
  437.         DrawString ("\pPress CMD or CMD-OPT & move buttons");
  438.         y += 20;
  439.         MoveTo (x, y);
  440.         DrawString ("\pDemo keys • available at all times");
  441.         y += 20;
  442.         x += 15;
  443.         MoveTo (x, y);
  444.         DrawString ("\pSPACE = hide/show the system cursor");
  445.         y += 15;
  446.         MoveTo (x, y);
  447.         DrawString ("\pS        = save current button positions");
  448.         y += 15;
  449.         MoveTo (x, y);
  450.         DrawString ("\pL        = load button positions from file");
  451.         y += 15;
  452.         MoveTo (x, y);
  453.         DrawString ("\pW       = write counter into data file");
  454.         y += 15;
  455.         MoveTo (x, y);
  456.         DrawString ("\pR        = read counter from data file");
  457.         y += 20;
  458.         x -= 15;
  459.         MoveTo (x, y);
  460.         DrawString ("\pThe buttons may be moved while playing");
  461.         y += 15;
  462.         MoveTo (x, y);
  463.         TextFace (italic);
  464.         DrawString ("\p(Colors and R/W strings are also stored in the file)");
  465.         TextFace (0);
  466.  
  467.         InsetRect (&r, 1, 1);
  468.         FrameRect (&r);
  469.     }
  470.  
  471.     SWSetPortToWindow(spriteWorldP);
  472.     TextFont (kFontIDNewYork);
  473.     TextSize (12);
  474.     TextMode (srcOr);
  475.     TextFace (bold);
  476.  
  477.  
  478.     //
  479.     // STEP #7: update the SpriteWorld and run the animation
  480.     //
  481.  
  482.     SWGLoadSpritesInLayer (buttonsLayerP);        // before first SW update (does not need buttons module to be inited)
  483.  
  484.     FingerCursorHandle = GetCursor(128);
  485.     HLock((Handle)FingerCursorHandle);
  486.     SWUpdateSpriteWorld(spriteWorldP, true);
  487.     SWSetSpriteWorldMaxFPS( spriteWorldP, kMaxFPS );
  488.     SWSyncSpriteWorldToVBL(spriteWorldP, kSyncToVBL);
  489.     
  490.     paddleSpriteP->userData=0;                    //Set up wiggle data which allows the demo paddle to move slightly erratically
  491.     PaddleWiggle=-1;
  492.  
  493.     SetUpDemoSprites();
  494.     SWGInitButtonSpriteWorld(SetButtonCursor);
  495.     
  496.     QuitBreakOut=false;
  497.  
  498.     // keep a running count of the saves using the persistence file [DB]
  499.     err = SWGOpenPersistenceFile ();
  500.     SWGErrorReportingStub (err);
  501.     err = SWGLoadRecord ((Ptr)&countSaves, sizeof (countSaves), demoRez + 1);
  502.     SWGErrorReportingStub (err);
  503.     SWGClosePersistenceFile ();
  504.  
  505.     while (!QuitBreakOut)
  506.     {
  507.         while ( GetOSEvent( (keyDownMask), &event ) )
  508.         {
  509.             char    key = event.message & charCodeMask;
  510.  
  511.             if (((event.message & keyCodeMask) >> 8)==0x35) QuitBreakOut=true;    //User hit esc key - abort game
  512.  
  513.             ProcessDemoCommands (key);                                            // [DB]
  514.         }
  515.  
  516.         SWProcessSpriteWorld(spriteWorldP);
  517.         if (spriteWorldP->frameHasOccurred)
  518.         {
  519.             SWGUpdateButtonData();                                                //must be called no more than once a frame
  520.  
  521.             // did we lose the last ball?
  522.             if (ballSpriteP->userData == 2)
  523.             {
  524.                 SetUpDemoSprites();
  525.             }
  526.             else if (BrickNum == 0)
  527.             {
  528.                 SetUpDemoSprites();
  529.             }
  530.             else if (GiveUpBreakOut)
  531.             {
  532.                 SetUpDemoSprites();
  533.             }
  534.  
  535.             if (! PauseBreakOut)
  536.             {
  537.                 // see if the ball has hit the paddle
  538.                 SWCollideSpriteLayer(spriteWorldP, paddleLayerP, ballLayerP);
  539.  
  540.                 // see if the ball has hit the bricks
  541.                 SWCollideSpriteLayer(spriteWorldP, ballLayerP, brickLayerP);
  542.             }
  543.  
  544.             SWAnimateSpriteWorld(spriteWorldP);
  545.  
  546.             // [DB] erase the demo counter control message
  547.             if ((eraseTime > 0) && (eraseTime < TickCount ()))
  548.             {
  549.                 SWUpdateSpriteWorld(spriteWorldP, true);
  550.                 eraseTime = 0;
  551.             }
  552.         }
  553.     }
  554.  
  555.  
  556.     //
  557.     // STEP #8: Clean up
  558.     //
  559.  
  560.     SWUnlockSpriteWorld(spriteWorldP);
  561.     SWDisposeSpriteWorld(spriteWorldP);
  562.     SWExitSpriteWorld();
  563.     
  564.     FlushEvents(everyEvent, 0);
  565.     ShowCursor();
  566.     cursorVisible = true;
  567. }
  568.  
  569.  
  570.  
  571. ///--------------------------------------------------------------------------------------
  572. // ProcessDemoCommands [DB]
  573. ///--------------------------------------------------------------------------------------
  574.  
  575. void ProcessDemoCommands (char key)
  576. {
  577.     OSErr    err;
  578.  
  579.     if (key == ' ')
  580.     {
  581.         cursorVisible = ! cursorVisible;
  582.         gButtonsAreActive = cursorVisible;
  583.         if (cursorVisible)
  584.             ShowCursor ();
  585.         else
  586.             HideCursor ();
  587.     }
  588.     else if (key == 's' || key == 'S')
  589.     {
  590.         SWGSaveSpritesInLayer (buttonsLayerP);
  591.     }
  592.     else if (key == 'l' || key == 'L')
  593.     {
  594.         SWGLoadSpritesInLayer (buttonsLayerP);
  595.     }
  596.     else if (key == 'w' || key == 'W')
  597.     {
  598.         RGBColor    black = {0,0,0};
  599.  
  600.         err = SWGOpenPersistenceFile ();
  601.         SWGErrorReportingStub (err);
  602.  
  603.         // will write a string
  604.         sprintf (demoStr, "Save #%ld, was %d bricks", ++countSaves, BrickNum);
  605.         err = SWGSaveString (demoStr, sizeof (demoStr), demoRez);
  606.         SWGErrorReportingStub (err);
  607.  
  608.         // will write a number
  609.         err = SWGSaveRecord ((Ptr)&countSaves, sizeof (countSaves), demoRez + 1);
  610.         SWGErrorReportingStub (err);
  611.  
  612.         SWGClosePersistenceFile ();
  613.  
  614.         if (eraseTime > 0)                                    // avoid dirty overwriting -- purely a cosmetic hack
  615.             SWUpdateSpriteWorld(spriteWorldP, true);
  616.  
  617.         MoveTo (moveBoundsRect.left + 2, moveBoundsRect.bottom - 3);
  618.         RGBForeColor (&infoTextColor);
  619.         DrawString ("\p WROTE: \"");
  620.         DrawString (c2pstr (demoStr));
  621.         DrawString ("\p\" ");
  622.         RGBForeColor (&black);
  623.         eraseTime = TickCount () + kEraseWritingTimer;
  624.     }
  625.     else if (key == 'r' || key == 'R')
  626.     {
  627.         RGBColor    black = {0,0,0};
  628.  
  629.         err = SWGOpenPersistenceFile ();
  630.         SWGErrorReportingStub (err);
  631.  
  632.         // read the string
  633.         err = SWGLoadString (demoStr, sizeof (demoStr), demoRez);
  634.         SWGErrorReportingStub (err);
  635.  
  636.         // read the number
  637.         err = SWGLoadRecord ((Ptr)&countSaves, sizeof (countSaves), demoRez + 1);
  638.         SWGErrorReportingStub (err);
  639.  
  640.         SWGClosePersistenceFile ();
  641.  
  642.         if (eraseTime > 0)                                    // avoid dirty overwriting -- purely a cosmetic hack
  643.             SWUpdateSpriteWorld(spriteWorldP, true);
  644.  
  645.         MoveTo (moveBoundsRect.left + 2, moveBoundsRect.bottom - 3);
  646.         RGBForeColor (&infoTextColor);
  647.         DrawString ("\p READ: \"");
  648.         DrawString (c2pstr (demoStr));
  649.         DrawString ("\p\" ");
  650.         RGBForeColor (&black);
  651.         eraseTime = TickCount () + kEraseReadingTimer;
  652.     }
  653. }
  654.  
  655.  
  656. ///--------------------------------------------------------------------------------------
  657. // BallCollideProc
  658. ///--------------------------------------------------------------------------------------
  659.  
  660. SW_FUNC void BallCollideProc(SpritePtr ballSpriteP, SpritePtr brickSpriteP, Rect* sectRect)
  661. {
  662.     SInt16        offset;
  663.     SInt16        vertMoveDelta = ballSpriteP->vertMoveDelta;
  664.     SInt16        horizMoveDelta = ballSpriteP->horizMoveDelta;
  665.  
  666.  
  667.     if (vertMoveDelta < 0)
  668.         vertMoveDelta = -vertMoveDelta;
  669.     
  670.     if (horizMoveDelta < 0)
  671.         horizMoveDelta = -horizMoveDelta;
  672.     
  673.     if (brickSpriteP->isVisible)
  674.     {
  675.         SWSetSpriteVisible(brickSpriteP, false);
  676.         BrickNum--;
  677.  
  678.  
  679.         
  680.         if (vertMoveDelta < sectRect->bottom - sectRect->top)
  681.         {
  682.                 // Hit left or right side of brick
  683.             
  684.                 // Reverse direction
  685.             ballSpriteP->horizMoveDelta = -ballSpriteP->horizMoveDelta;
  686.             
  687.                 // "Bounce" ball off bricks
  688.             offset = (sectRect->right - sectRect->left) * 2;
  689.             if (ballSpriteP->horizMoveDelta < 0)
  690.                 offset = -offset;
  691.             
  692.             SWOffsetSprite(ballSpriteP, offset, 0);
  693.         }
  694.         else if (horizMoveDelta < sectRect->right - sectRect->left)
  695.         {
  696.                 // Hit top or bottom of brick
  697.             
  698.                 // Reverse direction
  699.             ballSpriteP->vertMoveDelta = -ballSpriteP->vertMoveDelta;
  700.             
  701.                 // "Bounce" ball off bricks
  702.             offset = (sectRect->bottom - sectRect->top) * 2;
  703.             if (ballSpriteP->vertMoveDelta < 0)
  704.                 offset = -offset;
  705.             
  706.             SWOffsetSprite(ballSpriteP, 0, offset);
  707.         }
  708.         else
  709.         {
  710.                 // Hit corner of brick
  711.                 
  712.             if ((sectRect->right - sectRect->left) > (sectRect->bottom - sectRect->top) )
  713.             {
  714.                     // Hit left or right side of brick
  715.                 
  716.                     // Reverse direction
  717.                 ballSpriteP->horizMoveDelta = -ballSpriteP->horizMoveDelta;
  718.                 
  719.                     // "Bounce" ball off bricks
  720.                 offset = (sectRect->right - sectRect->left) * 2;
  721.                 if (ballSpriteP->horizMoveDelta < 0)
  722.                     offset = -offset;
  723.                 
  724.                 SWOffsetSprite(ballSpriteP, offset, 0);
  725.             }
  726.             else
  727.             {
  728.                     // Hit top or bottom of brick
  729.                 
  730.                     // Reverse direction
  731.                 ballSpriteP->vertMoveDelta = -ballSpriteP->vertMoveDelta;
  732.                 
  733.                     // "Bounce" ball off bricks
  734.                 offset = (sectRect->bottom - sectRect->top) * 2;
  735.                 if (ballSpriteP->vertMoveDelta < 0)
  736.                     offset = -offset;
  737.                 
  738.                 SWOffsetSprite(ballSpriteP, 0, offset);
  739.             }
  740.         }
  741.     }
  742. }
  743.  
  744.  
  745. ///--------------------------------------------------------------------------------------
  746. // PaddleCollideProc
  747. ///--------------------------------------------------------------------------------------
  748.  
  749. SW_FUNC void PaddleCollideProc(SpritePtr paddleSpriteP, SpritePtr ballSpriteP, Rect* sectRect)
  750. {
  751.     SInt16    paddleMid = (paddleSpriteP->destFrameRect.right - 
  752.                             paddleSpriteP->destFrameRect.left)/2;
  753.     SInt16    ballMid = (ballSpriteP->destFrameRect.right - 
  754.                             ballSpriteP->destFrameRect.left)/2;
  755.             
  756.     if ( (ballSpriteP->destFrameRect.bottom - ballSpriteP->vertMoveDelta) 
  757.             > paddleSpriteP->destFrameRect.bottom )
  758.         return;                            // Return if ball did not hit above bottom of paddle
  759.     
  760.     
  761.         // Set ball direction according to position hit on paddle
  762.     if (ballSpriteP->destFrameRect.left + ballMid >
  763.          paddleSpriteP->destFrameRect.left + paddleMid)
  764.     {
  765.         ballSpriteP->horizMoveDelta = ( (ballSpriteP->destFrameRect.left + ballMid) - 
  766.                 (paddleSpriteP->destFrameRect.left + paddleMid) )/4;
  767.                 
  768.         if (ballSpriteP->horizMoveDelta > 0)
  769.             ballSpriteP->vertMoveDelta = kBallVertDelta - ballSpriteP->horizMoveDelta/2;
  770.         else
  771.             ballSpriteP->vertMoveDelta = kBallVertDelta + ballSpriteP->horizMoveDelta/2;
  772.         
  773.         if (ballSpriteP->horizMoveDelta == 0)
  774.             ballSpriteP->horizMoveDelta++;
  775.     }
  776.     else
  777.     {
  778.         ballSpriteP->horizMoveDelta = ( (ballSpriteP->destFrameRect.left + ballMid) - 
  779.                 (paddleSpriteP->destFrameRect.left + paddleMid) )/4;
  780.                 
  781.         if (ballSpriteP->horizMoveDelta > 0)
  782.             ballSpriteP->vertMoveDelta = kBallVertDelta - ballSpriteP->horizMoveDelta/2;
  783.         else
  784.             ballSpriteP->vertMoveDelta = kBallVertDelta + ballSpriteP->horizMoveDelta/2;
  785.         
  786.         if (ballSpriteP->horizMoveDelta == 0)
  787.             ballSpriteP->horizMoveDelta--;
  788.     }
  789.  
  790.     
  791.         // If ball was moving down, turn it around
  792.     if (ballSpriteP->vertMoveDelta > 0)
  793.         ballSpriteP->vertMoveDelta = -ballSpriteP->vertMoveDelta;
  794.     
  795.     if ( (ballSpriteP->destFrameRect.bottom - ballSpriteP->vertMoveDelta) 
  796.             > paddleSpriteP->destFrameRect.top )
  797.     {
  798.         SWOffsetSprite(ballSpriteP, 0, sectRect->top - sectRect->bottom);
  799.     }
  800.     
  801. }
  802.  
  803.  
  804. ///--------------------------------------------------------------------------------------
  805. // SetUpPaddle
  806. ///--------------------------------------------------------------------------------------
  807.  
  808. SW_FUNC void SetUpPaddle(SpritePtr paddleSpriteP)
  809. {
  810.     SInt16    middle = (paddleSpriteP->moveBoundsRect.right - 
  811.                         paddleSpriteP->moveBoundsRect.left) / 2;
  812.     SInt16    paddleWidth = (paddleSpriteP->destFrameRect.right - 
  813.                             paddleSpriteP->destFrameRect.left);
  814.     Point    globalPoint;
  815.     
  816.     
  817.     GetMouse(&newPoint);
  818.     globalPoint = newPoint;
  819.     LocalToGlobal(&globalPoint);
  820.     
  821.     if (globalPoint.h < middle)
  822.     {
  823.         SWMoveSprite(paddleSpriteP, paddleSpriteP->moveBoundsRect.left +
  824.                                     globalPoint.h, paddleSpriteP->moveBoundsRect.bottom - 30);
  825.     }
  826.     else if (qd.screenBits.bounds.right - globalPoint.h < middle)
  827.     {
  828.         SWMoveSprite(paddleSpriteP, paddleSpriteP->moveBoundsRect.right+1 -
  829.                                     (qd.screenBits.bounds.right - globalPoint.h) - paddleWidth, 
  830.                                     paddleSpriteP->moveBoundsRect.bottom - 30);
  831.     }
  832.     else
  833.     {
  834.         SWMoveSprite(paddleSpriteP, paddleSpriteP->moveBoundsRect.left +
  835.                         middle - paddleWidth/2, paddleSpriteP->moveBoundsRect.bottom - 30);
  836.     }
  837. }
  838.  
  839.  
  840. ///--------------------------------------------------------------------------------------
  841. // PaddleMoveProc
  842. ///--------------------------------------------------------------------------------------
  843.  
  844. SW_FUNC void PaddleMoveProc(SpritePtr paddleSpriteP)
  845. {
  846.     oldPoint = newPoint;
  847.  
  848.     if (PauseBreakOut)
  849.         return;
  850.  
  851.     GetMouse(&newPoint);
  852.  
  853.     SWOffsetSprite(paddleSpriteP, newPoint.h - oldPoint.h, 0);
  854.     
  855.     if (paddleSpriteP->destFrameRect.left < paddleSpriteP->moveBoundsRect.left)
  856.     {
  857.         SWOffsetSprite(paddleSpriteP, (paddleSpriteP->moveBoundsRect.left - 
  858.                             paddleSpriteP->destFrameRect.left) , 0);
  859.     }
  860.     else if (paddleSpriteP->destFrameRect.right > paddleSpriteP->moveBoundsRect.right)
  861.     {
  862.         SWOffsetSprite(paddleSpriteP, (paddleSpriteP->moveBoundsRect.right - 
  863.                             paddleSpriteP->destFrameRect.right) , 0);
  864.     }
  865. }
  866.  
  867.  
  868. ///--------------------------------------------------------------------------------------
  869. // PaddleDemoMoveProc
  870. ///--------------------------------------------------------------------------------------
  871.  
  872. SW_FUNC void PaddleDemoMoveProc(SpritePtr paddleSpriteP)
  873. {
  874.  
  875.     // During the demo we must do this wiggle nonsense - or else the ball will always hit the
  876.     // paddle in the exact same spot, which causes it to bounce at the exact same angle,
  877.     // often leading into a infinite loop - which is boring.  So we add a wiggle factor.
  878.     
  879.     paddleSpriteP->userData+=PaddleWiggle;
  880.     
  881.     if (paddleSpriteP->userData<-10)
  882.         {
  883.         PaddleWiggle=1;
  884.         paddleSpriteP->userData=-10;
  885.         }
  886.     if (paddleSpriteP->userData>40)
  887.         {
  888.         PaddleWiggle=-1;
  889.         paddleSpriteP->userData=40;
  890.         }
  891.     
  892.     SWMoveSprite(paddleSpriteP, ballSpriteP->destFrameRect.left-paddleSpriteP->userData, paddleSpriteP->moveBoundsRect.bottom - 30);
  893.     
  894.     if (paddleSpriteP->destFrameRect.left < paddleSpriteP->moveBoundsRect.left)
  895.     {
  896.         SWOffsetSprite(paddleSpriteP, (paddleSpriteP->moveBoundsRect.left - 
  897.                             paddleSpriteP->destFrameRect.left) , 0);
  898.     }
  899.     else if (paddleSpriteP->destFrameRect.right > paddleSpriteP->moveBoundsRect.right)
  900.     {
  901.         SWOffsetSprite(paddleSpriteP, (paddleSpriteP->moveBoundsRect.right - 
  902.                             paddleSpriteP->destFrameRect.right) , 0);
  903.     }
  904. }
  905.  
  906.  
  907. ///--------------------------------------------------------------------------------------
  908. // BallMoveProc
  909. ///--------------------------------------------------------------------------------------
  910.  
  911. SW_FUNC void BallMoveProc(SpritePtr srcSpriteP)
  912. {
  913.     register SInt16         inset;
  914.     
  915.     if (PauseBreakOut)
  916.         return;
  917.  
  918.         // Move the sprite
  919.     SWOffsetSprite(srcSpriteP, srcSpriteP->horizMoveDelta, srcSpriteP->vertMoveDelta);
  920.     
  921.  
  922.         // Check for collision with walls
  923.     if ((srcSpriteP->destFrameRect.left < srcSpriteP->moveBoundsRect.left) &&
  924.             (srcSpriteP->horizMoveDelta < 0))        // Past left bounds and moving left
  925.     {
  926.         srcSpriteP->horizMoveDelta *= -1;            // Reverse direction
  927.         inset = srcSpriteP->moveBoundsRect.left - srcSpriteP->destFrameRect.left;
  928.         SWOffsetSprite( srcSpriteP, inset * 2, 0 );    // "Bounce" sprite off bounds
  929.  
  930.     }
  931.     else if ((srcSpriteP->destFrameRect.right > srcSpriteP->moveBoundsRect.right)&&
  932.                 (srcSpriteP->horizMoveDelta > 0))    // Past right bounds and moving right
  933.     {
  934.         srcSpriteP->horizMoveDelta *= -1;            // Reverse direction
  935.         inset = srcSpriteP->moveBoundsRect.right - srcSpriteP->destFrameRect.right;
  936.         SWOffsetSprite( srcSpriteP, inset * 2, 0 );    // "Bounce" sprite off bounds
  937.     }
  938.  
  939.     if ((srcSpriteP->destFrameRect.top < srcSpriteP->moveBoundsRect.top) &&
  940.             (srcSpriteP->vertMoveDelta < 0))        // Past top bounds and moving up
  941.     {
  942.         srcSpriteP->vertMoveDelta *= -1;            // Reverse direction
  943.         inset = srcSpriteP->moveBoundsRect.top - srcSpriteP->destFrameRect.top;
  944.         SWOffsetSprite( srcSpriteP, 0, inset * 2 );    // "Bounce" sprite off bounds
  945.     }
  946.     else if ((srcSpriteP->oldFrameRect.top > srcSpriteP->moveBoundsRect.bottom)&&
  947.                 (srcSpriteP->vertMoveDelta > 0))    // Past bottom bounds and moving down
  948.     {
  949.         SysBeep(1);
  950.         srcSpriteP->userData++;
  951.  
  952.         SWSetSpriteLocation(srcSpriteP, -100, 50);
  953.  
  954.         SWSetSpriteMoveDelta(srcSpriteP, kBallHorizDelta, kBallVertDelta);
  955.     }
  956. }
  957.  
  958. // Set up all the sprites to start a game
  959. void SetUpGameSprites(void)
  960. {
  961.     HideCursor();
  962.     cursorVisible = false;
  963.  
  964.     ballSpriteP->userData=0;
  965.     
  966.     moveBoundsRect = srcWindowP->portRect;
  967.  
  968.         // set up the bricks
  969.     for (BrickNum = 0; BrickNum < kTotalNumberOfBricks; BrickNum++)
  970.     {
  971.         SWSetSpriteVisible(brickSpriteArray[BrickNum], true);
  972.     }
  973.  
  974.         // hide/show button sprites because we are playing a game
  975.     SWSetSpriteVisible((SpritePtr)playButtonSpritePtr, false);
  976.     SWSetSpriteVisible((SpritePtr)quitButtonSpritePtr, false);
  977.     SWSetSpriteVisible((SpritePtr)disabledButtonSpritePtr, false);
  978.     SWSetSpriteVisible((SpritePtr)pauseButtonSpritePtr, true);            // [DB]
  979.     SWSetSpriteVisible((SpritePtr)giveUpButtonSpritePtr, true);            // [DB]
  980.     
  981.         // set the ball’s movement characteristics
  982.     SWMoveSprite(ballSpriteP, - 100, 50);
  983.     SWSetSpriteMoveBounds(ballSpriteP, &moveBoundsRect);
  984.     SWSetSpriteMoveDelta(ballSpriteP, kBallHorizDelta, kBallVertDelta);
  985.     SWSetSpriteMoveProc(ballSpriteP, BallMoveProc);
  986.     SWSetSpriteCollideProc(ballSpriteP, BallCollideProc);
  987.  
  988.         // set the paddle’s movement characteristics
  989.     SWSetSpriteMoveBounds(paddleSpriteP, &moveBoundsRect);
  990.     SetUpPaddle(paddleSpriteP);
  991.     SWSetSpriteMoveProc(paddleSpriteP, PaddleMoveProc);
  992.     SWSetSpriteCollideProc(paddleSpriteP, PaddleCollideProc);
  993.     
  994.     //
  995.     // Set the DrawProcs to BlitPixie
  996.     //
  997.  
  998.         // Set the screen drawProcs
  999.     if (spriteWorldP->pixelDepth == 8)        // 256 colors
  1000.     {
  1001.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
  1002.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
  1003.     }
  1004.     else if ( !(SW_PPC && spriteWorldP->pixelDepth < 8) )    // Not 256 colors
  1005.     {
  1006.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
  1007.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
  1008.     }
  1009.     SWSetSpriteWorldMaxFPS( spriteWorldP, kMaxFPS );
  1010. }
  1011.  
  1012.  
  1013. // Set up all the sprites to start the demo
  1014. void SetUpDemoSprites(void)
  1015. {
  1016.     ShowCursor();
  1017.     cursorVisible = true;
  1018.  
  1019.     ballSpriteP->userData=0;
  1020.     
  1021.     moveBoundsRect = srcWindowP->portRect;
  1022.  
  1023.         // set up the bricks
  1024.     for (BrickNum = 0; BrickNum < kTotalNumberOfBricks; BrickNum++)
  1025.     {
  1026.         SWSetSpriteVisible(brickSpriteArray[BrickNum], true);
  1027.     }
  1028.  
  1029.         // show button sprites because the demo is running
  1030.     SWSetSpriteVisible((SpritePtr)playButtonSpritePtr, true);
  1031.     SWSetSpriteMoveProc((SpritePtr)playButtonSpritePtr, ButtonMoveProc);
  1032.     SWGEnableButton(playButtonSpritePtr, true);
  1033.     
  1034.     SWSetSpriteVisible((SpritePtr)quitButtonSpritePtr, true);
  1035.     SWSetSpriteMoveProc((SpritePtr)quitButtonSpritePtr, ButtonMoveProc);
  1036.     SWGEnableButton(quitButtonSpritePtr, true);
  1037.     
  1038.     SWSetSpriteVisible((SpritePtr)disabledButtonSpritePtr, true);
  1039.     SWSetSpriteMoveProc((SpritePtr)disabledButtonSpritePtr, ButtonMoveProc);
  1040.     SWGEnableButton(disabledButtonSpritePtr, false);
  1041.     
  1042.     SWSetSpriteVisible((SpritePtr)pauseButtonSpritePtr, false);                        // [DB]
  1043.     SWSetSpriteMoveProc((SpritePtr)pauseButtonSpritePtr, ButtonMoveProc);            // [DB]
  1044.     SWGEnableButton(pauseButtonSpritePtr, true);                                    // [DB]
  1045.     
  1046.     SWSetSpriteVisible((SpritePtr)giveUpButtonSpritePtr, false);                    // [DB]
  1047.     SWSetSpriteMoveProc((SpritePtr)giveUpButtonSpritePtr, ButtonMoveProc);            // [DB]
  1048.     SWGEnableButton(giveUpButtonSpritePtr, true);                                    // [DB]
  1049.     
  1050.         // set the ball’s movement characteristics
  1051.     SWMoveSprite(ballSpriteP, - 100, 50);
  1052.     SWSetSpriteMoveBounds(ballSpriteP, &moveBoundsRect);
  1053.     SWSetSpriteMoveDelta(ballSpriteP, kBallHorizDelta, kBallVertDelta);
  1054.     SWSetSpriteMoveProc(ballSpriteP, BallMoveProc);
  1055.     SWSetSpriteCollideProc(ballSpriteP, BallCollideProc);
  1056.  
  1057.         // set the paddle’s movement characteristics
  1058.     SWSetSpriteMoveBounds(paddleSpriteP, &moveBoundsRect);
  1059.     SetUpPaddle(paddleSpriteP);
  1060.     SWSetSpriteMoveProc(paddleSpriteP, PaddleDemoMoveProc);
  1061.     SWSetSpriteCollideProc(paddleSpriteP, PaddleCollideProc);
  1062.     
  1063.     //
  1064.     // Set the Screen DrawProcs to use Quickdraw
  1065.     //
  1066.  
  1067.         // Set the screen drawProcs
  1068.     if (spriteWorldP->pixelDepth == 8)        // 256 colors
  1069.     {
  1070.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, SWStdWorldDrawProc);            // During demos we must use copybits to draw to the screen because the
  1071.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);    // cursor will be visible and so if we didnt it would leave artifacts
  1072.     }
  1073.     else if ( !(SW_PPC && spriteWorldP->pixelDepth < 8) )    // Not 256 colors
  1074.     {
  1075.         SWSetSpriteWorldScreenDrawProc(spriteWorldP, SWStdWorldDrawProc);
  1076.         SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
  1077.     }
  1078.     SWSetSpriteWorldMaxFPS( spriteWorldP, 0 );
  1079.  
  1080.     GiveUpBreakOut = false;
  1081.     PauseBreakOut = false;
  1082. }
  1083.  
  1084. // ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
  1085. //                                        start of button-related routines
  1086. // ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
  1087. // These are just some generic button state proc.  They are called when the mouse is passed over or clicked
  1088. // in a button to change its appearance.  Right now they just set the appropriate frame of a generic sprite.
  1089. // You could put routines here to have animated buttons, sounds for mouseover or clicking or whatever you want.
  1090. // ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
  1091.  
  1092. SW_FUNC void GenericDrawButtonUpProc(ButtonSpritePtr srcButtonP, int ButtonStateChanged)
  1093. {
  1094.     if (ButtonStateChanged) SWSetCurrentFrameIndex((SpritePtr) srcButtonP, kButtonUp);
  1095. }
  1096.  
  1097. SW_FUNC void GenericDrawButtonMouseOverProc(ButtonSpritePtr srcButtonP, int ButtonStateChanged)
  1098. {
  1099.     if (ButtonStateChanged) SWSetCurrentFrameIndex((SpritePtr) srcButtonP, kButtonMouseOver);
  1100. }
  1101.  
  1102. SW_FUNC void GenericDrawButtonDownProc(ButtonSpritePtr srcButtonP, int ButtonStateChanged)
  1103. {
  1104.     if (ButtonStateChanged) SWSetCurrentFrameIndex((SpritePtr) srcButtonP, kButtonMouseDown);
  1105. }
  1106.  
  1107. SW_FUNC void GenericDrawButtonDisabledProc(ButtonSpritePtr srcButtonP, int ButtonStateChanged)
  1108. {
  1109.     if (ButtonStateChanged) SWSetCurrentFrameIndex((SpritePtr) srcButtonP, kButtonDisabled);
  1110. }
  1111.  
  1112. // ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
  1113.  
  1114. // When the buttons are clicked on these action Procs are called
  1115.  
  1116. SW_FUNC void PlayProc(SpritePtr srcSpriteP)
  1117. {
  1118.     #pragma unused (srcSpriteP)
  1119.  
  1120.     SetUpGameSprites();
  1121. }
  1122.  
  1123. SW_FUNC void QuitProc(SpritePtr srcSpriteP)
  1124. {
  1125.     #pragma unused (srcSpriteP)
  1126.  
  1127.     QuitBreakOut=true;
  1128. }
  1129.  
  1130.  
  1131. SW_FUNC void PauseProc(SpritePtr srcSpriteP)
  1132. {
  1133.     #pragma unused (srcSpriteP)
  1134.  
  1135.     PauseBreakOut = (! PauseBreakOut);
  1136. }
  1137.  
  1138.  
  1139. SW_FUNC void GiveUpProc(SpritePtr srcSpriteP)
  1140. {
  1141.     #pragma unused (srcSpriteP)
  1142.  
  1143.     GiveUpBreakOut = true;
  1144. }
  1145.  
  1146. SW_FUNC void SetButtonCursor(int CursorIsInAButton)
  1147. {
  1148.     if (CursorIsInAButton) SetCursor(*FingerCursorHandle);
  1149.     else SetCursor(&qd.arrow);
  1150. }
  1151.  
  1152. // ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
  1153. //                                        end of button-related routines
  1154. // ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
  1155.